from django.db import transaction
from django.utils import timezone
from .models import MatchmakingQueue
from apps.games.models import Game
import logging

logger = logging.getLogger(__name__)


class MatchmakingSystem:
    """匹配系统"""
    
    @staticmethod
    def find_match(user):
        """为用户寻找匹配"""
        try:
            user_queue = MatchmakingQueue.objects.get(user=user, is_active=True)
        except MatchmakingQueue.DoesNotExist:
            return None
        
        # 检查是否超时
        if user_queue.is_timeout:
            user_queue.is_active = False
            user_queue.save()
            return {'timeout': True, 'message': '匹配超时'}
        
        # 寻找匹配的对手
        opponent_queue = MatchmakingSystem._find_best_opponent(user_queue)
        
        if opponent_queue:
            with transaction.atomic():
                # 创建游戏
                game = Game.objects.create(
                    player1=user,
                    player2=opponent_queue.user,
                    player1_deck=user_queue.deck,
                    player2_deck=opponent_queue.deck,
                    status='playing'  # 匹配成功后直接开始游戏
                )
                
                # 创建第一回合
                from apps.games.models import GameRound
                GameRound.objects.create(
                    game=game,
                    round_number=1
                )
                
                # 将两个用户从队列中移除
                user_queue.is_active = False
                user_queue.save()
                opponent_queue.is_active = False
                opponent_queue.save()
                
                logger.info(f"匹配成功: {user.nickname} vs {opponent_queue.user.nickname}")
                
                return {
                    'game_id': game.id,
                    'opponent': {
                        'id': opponent_queue.user.id,
                        'nickname': opponent_queue.user.nickname,
                        'level': opponent_queue.user.level,
                        'win_rate': opponent_queue.user.win_rate
                    },
                    'player1': user.id,
                    'player2': opponent_queue.user.id
                }
        
        return None
    
    @staticmethod
    def _find_best_opponent(user_queue):
        """寻找最佳对手"""
        user_rating = user_queue.matchmaking_rating
        wait_time = user_queue.wait_time
        
        # 动态调整搜索范围（等待时间越长，范围越大）
        base_range = user_queue.search_range
        expanded_range = base_range + (wait_time // 30) * 50  # 每30秒扩大50分范围
        
        # 寻找评分相近的对手，使用 select_for_update 避免竞态条件
        candidates = MatchmakingQueue.objects.select_for_update().filter(
            is_active=True,
            matchmaking_rating__gte=user_rating - expanded_range,
            matchmaking_rating__lte=user_rating + expanded_range
        ).exclude(user=user_queue.user).order_by('joined_at')
        
        if candidates.exists():
            # 优先选择评分最接近的对手
            best_opponent = min(candidates, 
                              key=lambda x: abs(x.matchmaking_rating - user_rating))
            return best_opponent
        
        # 如果没有找到合适的对手，检查是否有超时的玩家可以匹配
        timeout_players = MatchmakingQueue.objects.select_for_update().filter(
            is_active=True,
            joined_at__lt=timezone.now() - timezone.timedelta(seconds=120)  # 等待超过2分钟
        ).exclude(user=user_queue.user).order_by('joined_at')
        
        if timeout_players.exists():
            return timeout_players.first()
        
        return None
    
    @staticmethod
    def create_game(player1, player2, player1_deck, player2_deck):
        """创建游戏房间"""
        with transaction.atomic():
            game = Game.objects.create(
                player1=player1,
                player2=player2,
                player1_deck=player1_deck,
                player2_deck=player2_deck,
                status='waiting'
            )
            return game
    
    @staticmethod
    def cleanup_expired_queues():
        """清理过期的匹配队列"""
        expired_queues = MatchmakingQueue.objects.filter(
            is_active=True,
            joined_at__lt=timezone.now() - timezone.timedelta(seconds=600)  # 10分钟
        )
        
        count = expired_queues.count()
        if count > 0:
            expired_queues.update(is_active=False)
            logger.info(f"清理了 {count} 个过期的匹配队列")
        
        return count
    
    @staticmethod
    def get_matchmaking_stats():
        """获取匹配统计信息"""
        active_queues = MatchmakingQueue.objects.filter(is_active=True)
        
        stats = {
            'active_players': active_queues.count(),
            'average_wait_time': 0,
            'rating_distribution': {},
            'level_distribution': {}
        }
        
        if active_queues.exists():
            # 计算平均等待时间
            total_wait_time = sum(queue.wait_time for queue in active_queues)
            stats['average_wait_time'] = total_wait_time // active_queues.count()
            
            # 评分分布
            ratings = [queue.matchmaking_rating for queue in active_queues]
            stats['rating_distribution'] = {
                'min': min(ratings),
                'max': max(ratings),
                'avg': sum(ratings) // len(ratings)
            }
            
            # 等级分布
            levels = [queue.user.level for queue in active_queues]
            level_count = {}
            for level in levels:
                level_count[level] = level_count.get(level, 0) + 1
            stats['level_distribution'] = level_count
        
        return stats
